use std::{collections::{VecDeque, HashMap}, sync::Arc};

use crate::{constants::DefaultFingerprintType, chunk::Chunk};

use super::{XcontainerWriter};

pub struct WorkSpace {
    enable:bool,
    write_buf:VecDeque<Arc<XcontainerWriter>>,
    cur_write:Option<Arc<XcontainerWriter>>,
    recent_buf:HashMap<DefaultFingerprintType,Arc<Chunk>>,
}

impl WorkSpace {
    pub fn new() -> Self {
        Self {
            enable:true,
            cur_write:None,
            write_buf:VecDeque::new(),
            recent_buf:HashMap::new(),
        }
    }

    pub fn find_in_work_space(&self,fp:&DefaultFingerprintType) -> Option<Arc<Chunk>> {
        let chunk = self.recent_buf.get(fp);
        if chunk.is_some() { return chunk.map(|c|c.clone()); }
        for xcon in self.write_buf.iter().chain(self.cur_write.iter()) { 
            let result = xcon.find(fp);
            if result.is_some() { return result.map(|c|c.clone()); }
        }
        None
    }


    pub fn insert_to_recent_buffer(&mut self,chunk:Arc<Chunk>) {
        self.recent_buf.insert(*chunk.fp(), chunk);
    }

    pub fn insert_to_write_buffer(&mut self,xcon:Arc<XcontainerWriter>) {
        self.write_buf.push_back(xcon.clone());
        for chunk in xcon.inner() as &Vec<Arc<Chunk>> {
            self.recent_buf.remove(chunk.fp());
        }
    }

    pub fn enable(&self) -> bool {
        self.enable
    }

    pub fn disable(&mut self) {
        self.enable = false;
    }

    pub fn next_write_xcon(&mut self) -> Option<Arc<XcontainerWriter>> {
        let next_con = self.write_buf.pop_front();
        self.cur_write = next_con.clone();
        next_con
    }

    pub fn current_xcon(&self) -> Option<Arc<XcontainerWriter>> {
        self.cur_write.clone()
    }
}